/*  This file is part of LitSearch.

    LitSearch is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    LitSearch is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with LitSearch; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */

package de.fhbrs.litsearch;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.softtech.jdbc.SQLResults;

/**
 * Handles application-specific settings
 *
 * @version 	1.0 6 Jan 2006
 * @author 		Marco Werner
 * 
 */
public class SettingsBean {
	private String ipRangeError;
	private LanguageBean languageObj;
	
	/** 
     * Set all instance variables to default values
     */
	public SettingsBean() {
		this.ipRangeError = "";
		this.languageObj = null;
	}
	
	/** 
     * Set upper limit for search results
     * @param searchLimit Search limit as a string
     */
	public void setSearchLimit(String searchLimit) {
		this.setValue("searchLimit", searchLimit);
	}
	
	/** 
     * Get upper limit for search results
     */
	public int getSearchLimitFromDB() {
		int searchLimit = 1000;
		try {
			searchLimit = Integer.parseInt(this.getValue("searchLimit"));
		} catch(Exception e) { }
		return searchLimit;
	}
	
	/** 
     * Set amount of results to be displayed on a result page
     * @param resultsPerPage Amount of results to be displayed on a result page as a string
     */
	public void setResultsPerPage(String resultsPerPage) {
		this.setValue("resultsPerPage", resultsPerPage);
	}
	
	/** 
     * Get amount of results to be displayed on a result page
     */
	public int getResultsPerPageFromDB() {
		int resultsPerPage = 20;
		try {
			resultsPerPage = Integer.parseInt(this.getValue("resultsPerPage"));
		} catch(Exception e) { }
		return resultsPerPage;
	}
	
	/** 
     * Set IP range for which the administration functions are visible
     * @param ipRange IP range as a string (accepted format: xxx.yyy.zzz.*)
     */
	public void setIpRange(String ipRange) {
		this.ipRangeError = "";
		if (ipRange.matches("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\/([0-9]|[1-2][0-9]|30|31|32)$")) this.setValue("ipRange", ipRange);
		else this.ipRangeError = "<p class=\"red\">"+this.languageObj.getTextFor("admin.ipRangeInvalid")+"</p>";
	}
	
	/** 
     * Get value for specified parameter from database
     * @param parameter Parameter as a string
     * @return Value for the specified parameter as a string
     */
	private String getValue(String parameter) {
		String value = "";
		JDBCBean dbCon = new JDBCBean();
		SQLResults res = dbCon.getResultSet("select * from settings where parameter=\"" + parameter + "\"");
		if (res.getRowCount() > 0) value = res.getString(0,"value");
		return value;
	}
	
	/** 
     * Set value for specified parameter in database
     * @param parameter Parameter as a string
     * @param value Value as a String
     */
	private void setValue(String parameter, String value) {
		JDBCBean dbCon = new JDBCBean();
		dbCon.executeQuery("UPDATE settings SET value='" + value + "' WHERE parameter=\"" + parameter + "\"");
	}
	
	/** 
     * Set language object to active language object from jsp-file
     * @param languageObj Language object from jsp-file
     */
	public void setLanguage(LanguageBean languageObj) {
		this.languageObj = languageObj;
	}
	
	/** 
     * Get search limit selection as HTML select
     * @return String with HTML select
     */
	public String getSearchLimitSelect() {
        String searchLimitSelect = "<select name=\"searchLimit\" size=\"1\">";
        int value = 0;
        try {
        	value = Integer.parseInt(this.getValue("searchLimit"));
        } catch (Exception e) { }
        for (int i=500; i<=5000; i+=500) {
        	searchLimitSelect += "<option value=\""+i+"\" ";
        	if (i == value) searchLimitSelect += "selected";
        	searchLimitSelect += ">"+i+"</option>";
        }
        searchLimitSelect += "</select>";
      return searchLimitSelect;
	}
	
	/** 
     * Get results per page selection as HTML select
     * @return String with HTML select
     */
	public String getResultsPerPageSelect() {
        String resultsPerPageSelect = "<select name=\"resultsPerPage\" size=\"1\">";
        int value = 0;
        try {
        	value = Integer.parseInt(this.getValue("resultsPerPage"));
        } catch (Exception e) { }
        for (int i=10; i<=50; i+=5) {
        	resultsPerPageSelect += "<option value=\""+i+"\" ";
        	if (i == value) resultsPerPageSelect += "selected";
        	resultsPerPageSelect += ">"+i+"</option>";
        }
        resultsPerPageSelect += "</select>";
      return resultsPerPageSelect;
	}
	
	/** 
     * Get IP range from database
     * @return IP range as a string
     */
	public String getIpRange() {
		return this.getValue("ipRange");
	}
	
	/** 
     * Get IP range from database
     * @return IP range as a string
     */
	public String getIpRangeError() {
		return this.ipRangeError;
	}
	
	/** 
     * Tests if supplied IP address fits in IP range stored in database
     * @param ip IP address as a String
     * @return true if IP address is in range or equals 127.0.0.1, false otherwise
     */
	public boolean isInIpRange(String ip) {
		if (ip.equals("127.0.0.1")) return true;
		byte[] mask = new byte[4];
		byte[] ipToCheck = new byte[4];
		byte[] ipFromRange = new byte[4];
		int subnetMask;
		String tempMask = "";
		String tempIPtoCheck[] = ip.split("\\.");
		String range = this.getValue("ipRange");
		String tempIPFromRange[] = range.substring(0, range.indexOf("/")).split("\\.");
		for (int i = 0; i < tempIPFromRange.length; i++) {
			try {
				ipFromRange[i] = (byte) Integer.parseInt(tempIPFromRange[i]);
			} catch(NumberFormatException nfe) { return false; }
		}
		try {
			subnetMask = Integer.parseInt(range.substring(range.indexOf("/")+1));
		} catch(NumberFormatException nfe) { return false; }
		for (int j = 1; j <= subnetMask; j++) {
			tempMask += "1";
		}
		for (int k = 1; k <= 32 - subnetMask; k++) {
			tempMask += "0";
		}
		try {
			mask[0] = (byte) Integer.parseInt(tempMask.substring(0,7));
			mask[1] = (byte) Integer.parseInt(tempMask.substring(8,15));
			mask[2] = (byte) Integer.parseInt(tempMask.substring(16,23));
			mask[3] = (byte) Integer.parseInt(tempMask.substring(24,31));
		} catch(NumberFormatException nfe) { return false; }
		for (int l = 0; l < tempIPtoCheck.length; l++) {
			try {
				ipToCheck[l] = (byte) Integer.parseInt(tempIPtoCheck[l]);
			} catch(NumberFormatException nfe) { return false; }
		}
        for (int i = 0; i < 4; i++) {
        	if (((ipToCheck[i] ^ ipFromRange[i]) & mask[i]) != 0) return false;
        }
        return true;
	}
	
	/**
	 * Get the applications build information (date and time) from a file
	 * @return build date and time from file
	 */
	public String getBuildInfo() {
		String buildInfo = "";
		InputStream in = this.getClass().getResourceAsStream("build.nfo");
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			buildInfo = br.readLine();
			in.close();
		} catch(Exception e) { System.out.print("<p class=\"debug\">[Error: File build.nfo could not be read!]</p>"); }
		if (buildInfo == null) buildInfo = "????????-????";
		return buildInfo;
	}
}
